﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Timers;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.Reflection;
using System.Xml;
using System.Threading;
using ApplicationList;
using UpdateList;
using OSList;
using System.Linq.Expressions;



namespace AppScan
{
    public partial class Form1 : Form
    {
        #region GLOBAL VARS
        //public string[] targets;
        static ReaderWriterLockSlim _rw = new ReaderWriterLockSlim();
        public static List<Targets> targets = new List<Targets>();
        public List<reglist> r1 = new List<reglist>();
        System.Timers.Timer time = new System.Timers.Timer(1000);
        // This delegate enables asynchronous calls for setting
        // the text property on a TextBox control.
        delegate void SetTextCallback(string text);
        delegate void SetTextCallback2(RichTextBox rtb);
        delegate void SetActiveBandCallback(Guifreaks.NavigationBar.NaviBand nv1);
        delegate void SetActiveDGVCallback(DataGridView dgv);

        public delegate void TreeActionDelegate(Color color);

        // This thread is used to demonstrate both thread-safe and
        // unsafe ways to call a Windows Forms control.
        private Thread demoThread = null;
        System.Threading.Thread t = null; //new Thread(scan_done);
        public registry regg = new registry();
        public static string readData = null;
        StringBuilder sb = new StringBuilder();
        //Thread t;
        bool bscanning = false;
        //public static Extensions ext = new Extensions();
        private string prefix = string.Empty;
        private bool installpkg_scan = false;
        private bool killswitch = false;
        private bool qfe_scan = false;
        private bool reg_scan = false;
        private bool misc_scan = false;
        int nThreadCount = 100;
        int nTimeOut = 150;
        int timeout = 0;
        static BackgroundWorker _bw = new BackgroundWorker();
        public string username
        {
            set { user1 = value; }
        }
        private string user1 = "test";
        public bool exported = false;
        public bool firstrun = true;
        public string ip_addr = string.Empty;
        private string pass1 = String.Empty;
        System.Threading.Thread[] ScanThread; // declares thread array
        public string password
        {
            set { pass1 = value; }
        }
        private static string host = null;
        private string xml_file = null;
        #endregion

        public Form1()
        {
            try
            {
                InitializeComponent();
                dataGridView1.Columns.Add("Item", "Item");
                dataGridView1.Columns.Add("Value", "Value");
                dataGridView1.RowHeadersVisible = false;
            }
            catch (Exception e)
            {
                MessageBox.Show("Error caught by blanket catch - usually something terrible has happened here.\n Please inform support with the following information: \n" + e);
            }
        }

        #region Start Scan
        private void newScanbtn_Click(object sender, EventArgs e)
        {
            //make sure we aren't scannign first

            if (!exported && !firstrun)
            {
                System.Windows.Forms.DialogResult msgBox;
                 msgBox = MessageBox.Show("Scan data has not been saved.  Would you like to do so now?\n (WARNING:  By not saving, you will lose all previous scan data!)", "Export Scan?", MessageBoxButtons.YesNo,MessageBoxIcon.Information) ;
                 if (msgBox == DialogResult.Yes)
                 {
                     ExportBtn1_Click(sender, e);
                 }
            }
            if (!firstrun)
            {
                int nNumOfThreadsToKill = (ScanThread.Length - 1);
                for (int lPtr = 0; lPtr <= nNumOfThreadsToKill; lPtr++)
                {
                    if (ScanThread[lPtr].IsAlive)
                    {
                        ScanThread[lPtr].Abort();
                       // this.Text = "Active Threads [" + (nThreadCount - lPtr) + "] - PLEASE WAIT";
                    };
                }
            }
            if (!bscanning)
            {
                
                bscanning = true;
                //this.newScanbtn0.BackgroundImage = Properties.Resources.Close;
                ToolTip tool1 = new ToolTip();
                //tool1.SetToolTip(this.newScanbtn0, "Stop Scan");
                this.naviBar2.ActiveBand = naviBand1;
                //this.newScanBtn0.Enabled = false;
                targets.Clear();

                CreateUserContext context = new CreateUserContext();
                CreateUserWizard wizard = new CreateUserWizard(context);
                wizard.ShowDialog();

                if (context.g2g)
                {
                    if (String.IsNullOrEmpty(context.domain))
                        user1 = context.username;
                    else
                        user1 = context.domain + "\\" + context.username;
                    pass1 = context.password;

                    installpkg_scan = context.installedpackages_scan;
                    qfe_scan = context.qfe_scan;
                    misc_scan = context.misc_scan;
                    reg_scan = context.reg;

                    if (!(String.IsNullOrEmpty(context.prefix)))
                        prefix = context.prefix;

                    get_targets_wizard(context.targeta);
                    //get_targets_file("targets.txt", 0);
                    fill_tree();

                    //foreach statement goes here
                    firstrun = false;
                    //_bw = new BackgroundWorker();
                    //_bw.DoWork += bw_DoWork;
                    //_bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                    //_bw.RunWorkerAsync();
                    ScanThread = new System.Threading.Thread[1];

                    ScanThread[0] = new System.Threading.Thread(start_thread);
                    ScanThread[0].Name = "Thread " + 0;
                    ScanThread[0].IsBackground = true;
                    ScanThread[0].Start();
                    exported = false;
                }
                else
                {
                    this.naviBar2.ActiveBand = naviBand2;
                    //this.newScanBtn0.Enabled = true;
                    //this.newScanbtn0.BackgroundImage = Properties.Resources.Add;
                    tool1 = new ToolTip();
                    //tool1.SetToolTip(this.newScanbtn0, "Start Scan");
                    bscanning = false;
                }
            }
            else
            {
                System.Windows.Forms.DialogResult msgBox;
                if (!(String.IsNullOrEmpty(ScanThread.ToString())))
                {
                int nNumOfThreadsToKill = (ScanThread.Length - 1);

                msgBox = MessageBox.Show("Are you sure you want to abort the scan?", "Abort Scan?", MessageBoxButtons.YesNo,MessageBoxIcon.Information) ;
                if (msgBox == DialogResult.Yes)
                {
                    for (int lPtr = 0; lPtr <= nNumOfThreadsToKill; lPtr++)
                    {
                        if (ScanThread[lPtr].IsAlive)
                        {
                            ScanThread[lPtr].Abort();
                            this.Text = "Active Threads [" + (nThreadCount - lPtr) + "] - PLEASE WAIT";
                        };
                    }
                    bscanning = false;
                    this.Text = "Advanced WMI Scanning Utility*";
                    //this.newScanbtn0.BackgroundImage = Properties.Resources.Add;
                    ToolTip tool1 = new ToolTip();
                    this.naviBar2.ActiveBand = naviBand2;
                    //this.newScanBtn0.Enabled = true;
                    //tool1.SetToolTip(this.newScanbtn0, "Start Scan");
                    MessageBox.Show("Scan aborted!");
                }
                }
            }
         }

        private void CancelScan_Click(object sender, EventArgs e)
        {
            if (bscanning)
            {
                System.Windows.Forms.DialogResult msgBox;
                if (!(String.IsNullOrEmpty(ScanThread.ToString())))
                {
                    int nNumOfThreadsToKill = (ScanThread.Length - 1);

                    msgBox = MessageBox.Show("Are you sure you want to abort the scan?", "Abort Scan?", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                    if (msgBox == DialogResult.Yes)
                    {
                        for (int lPtr = 0; lPtr <= nNumOfThreadsToKill; lPtr++)
                        {
                            if (ScanThread[lPtr].IsAlive)
                            {
                                ScanThread[lPtr].Abort();
                                this.Text = "Active Threads [" + (nThreadCount - lPtr) + "] - PLEASE WAIT";
                            };
                        }
                        bscanning = false;
                        this.Text = "Advanced WMI Scanning Utility*";
                        //this.newScanbtn0.BackgroundImage = Properties.Resources.Add;
                        ToolTip tool1 = new ToolTip();
                        this.naviBar2.ActiveBand = naviBand2;
                        this.newScanBtn0.Enabled = true;
                        //tool1.SetToolTip(this.newScanbtn0, "Start Scan");
                        MessageBox.Show("Scan aborted!");
                    }
                }
            }
        }

        private void start_thread()
        {
            int MAX = targets.Count;
            bool up = false;
            for (int i = 0; i < MAX; i++)
            {
                bool first = true;
                /***********************************
                 * Need to check first, if hosts are
                 * on-line.  We can use ping or tcp
                 * port135 and/or 22 depending on
                 * Scan type.  
                 * *********************************/
                up = host_up(targets[i].name, 135);
                //for future use, if ip.addr is present, use it, if not use hostname
                string hostname = targets[i].ipaddr.ToString();

               // useWMI_misc(targets[i].name, user1, pass1);
                if (up)
                {
                    targets[i].killswitch = false;
                    LogTextEvent(richTextBox1, Color.ForestGreen, "Host " + hostname + " is on-line, beginning WMI scans!");

                    if (!(string.IsNullOrEmpty(hostname)))
                    {
                        if (!(misc_scan))
                        {

                        }
                        if (misc_scan && !(targets[i].killswitch))
                        {
                            LogTextEvent(richTextBox1, Color.Black, "Beginning OS and misc scan on " + hostname);
                            //useWMIC(targets[i].name, user1, pass1, new string[] { "os", "list", "full" });
                            useWMI_misc(targets[i].name, user1, pass1);
                            //readData = "Finished OS/misc scan on " + targets[i].name;
                            LogTextEvent(richTextBox1, Color.Black, "Finished OS/misc scan on " + targets[i].name);
                        }

                        if (reg_scan)
                        {
                            try
                            {

                                readData = "Beginning reg unistall scan on " + hostname;
                                LogTextEvent(richTextBox1, Color.Black, readData);
                                string[] args = new string[3] { "query", @"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", @"/s" };
                                string subkey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
                                //string subkey = @"SOFTWARE\Microsoft\Windows";
                                //run_regq(args, targets[i].name);
                                //run_reg_csharp(targets[i].name, subkey);
                                targets[i].r1 = regg.WMI_readreg(hostname, user1, pass1, subkey);
                                subkey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products";
                                targets[i].r1 = regg.WMI_REG(hostname, user1, pass1, "HKLM", subkey, targets[i].r1);
                                readData = "Finished reg unistall scan!";// on " + targets[i].name;
                                LogTextEvent(richTextBox1, Color.Black, readData);
                            }
                            catch
                            {
                                MessageBox.Show("There was an error, attmpting to read from the registry\n");
                            }
                        }
                        //string reg = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
                        //string reg = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\";
                        if (installpkg_scan && !(targets[i].killswitch))
                        {
                            readData = "Beginning Installed Packages Scan on " + targets[i].name;
                            LogTextEvent(richTextBox1, Color.Black, readData);
                            useWMI_installedapps(targets[i].name, user1, pass1);
                            readData = "Finished Installed Packages Scan on " + targets[i].name;
                            LogTextEvent(richTextBox1, Color.Black, readData);
                        }

                        if (qfe_scan && !(targets[i].killswitch))
                        {
                            //useREG(targets[i].name, username, password, reg);
                            readData = "Beginning HotFix / Patch Scan on " + targets[i].name;
                            LogTextEvent(richTextBox1, Color.Black, readData);
                            //useWMIC(targets[i].name, user1, pass1, new string[] { "qfe", "list", "full" });
                            useWMI_qfe(targets[i].name, user1, pass1);
                            //readData = "Finished HotFix / Patch Scan on " + targets[i].name;
                            LogTextEvent(richTextBox1, Color.Black, "Finished HotFix / Patch Scan on " + targets[i].name);
                        }
                    }
                }
                    bool up2 = host_up(targets[i].name, 22);
                    if (up2)//Linux mode enabled
                    {
                    begin:
                        bool cont = false;
                        //pop up message box explaining that ssh will require credentials to be passed 
                        //Due to security constraints, when using current credentials,
                        //all hosts requiring ssh (Linux/Mac) will require credentials to at least be entered once.
                        //if they work, great, if not, prompt one additional time.
                        cont = get_credentials(targets[i].name);
                        if (cont)
                        {
                            //need to get current creds if possible
                            LogTextEvent(richTextBox1, Color.ForestGreen, "Host " + targets[i].name + " is on-line, beginning scans!");

                        again:
                            if (installpkg_scan)
                            {
                                tree_color(targets[i].name, Color.Orange);
                                run_packages_py("-s " + targets[i].name + " -u " + user1 + " -p " + pass1 + "", targets[i].name, 0);
                                if (misc_scan)
                                    tree_color(targets[i].name, Color.Orange);
                                else
                                    tree_color(targets[i].name, Color.Green);
                                if (sb.ToString().Contains("Bad authentication type"))
                                {
                                    tree_color(targets[i].name, true, "Bad auth type - invalid credentials");
                                    cont = get_credentials(targets[i].name);
                                    LogTextEvent(richTextBox1, Color.Red, "Bad credentials for " + targets[i].name + "!");
                                    if (cont && first)
                                    {
                                        first = false;
                                        goto again;
                                    }
                                }

                            }
                            if (misc_scan)
                            {
                                run_packages_py("-s " + targets[i].name + " -u " + user1 + " -p " + pass1 + " -o yes", targets[i].name, 1);
                                tree_color(targets[i].name, Color.Green);
                                if (sb.ToString().Contains("Bad authentication type"))
                                {
                                    tree_color(targets[i].name, true, "Bad auth type - invalid credentials");
                                    cont = get_credentials(targets[i].name);
                                    LogTextEvent(richTextBox1, Color.Red, "Bad credentials for " + targets[i].name + "!");
                                    if (cont && first)
                                    {
                                        first = false;
                                        goto again;
                                    }
                                }
                            }
                        }
                        else { goto begin; }
                    }
                    else
                    {
                        if (!up)
                        {
                            tree_color(targets[i].name, Color.Gray);
                            LogTextEvent(richTextBox1, Color.Red, "Host " + targets[i].name + " appears to be down");
                        }
                    }
                }
                //this.newScanbtn0.BackgroundImage = Properties.Resources.Add;
            //this.newScanBtn0.Enabled = true;
            //this.naviBar2.ActiveBand = naviBand2;
            this.SetActiveBand(naviBand2);
                this.bscanning = false;
                this.exported = false;
                MessageBox.Show("Scan Complete!");
                
        }

        //List will be required instead of dgv; we may need to implement an IFace here
        private void SetActiveView(DataGridView dgv)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.naviBar2.InvokeRequired)
            {
                SetActiveDGVCallback d = new SetActiveDGVCallback(SetActiveView);
                this.Invoke(d, new object[] { dgv });
            }
            else
            {
                this.dataGridView1.DataSource = dgv;
            }
        }

        private void SetActiveBand(Guifreaks.NavigationBar.NaviBand nv1)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.naviBar2.InvokeRequired)
            {
                SetActiveBandCallback d = new SetActiveBandCallback(SetActiveBand);
                this.Invoke(d, new object[] { nv1 });
            }
            else
            {
                this.naviBar2.ActiveBand = nv1;
            }
        }


        private bool host_up(string hostname, int port)
        {
            bool up = false;
            //string hostname = "localhost";
            IPAddress ipa;
            try
            {
                bool test = IPAddress.TryParse(hostname, out ipa);

                if (!(test))
                {
                    ipa = (IPAddress)Dns.GetHostAddresses(hostname)[0];
                }
            }
            catch
            {
                
            }
            System.Timers.Timer timer = new System.Timers.Timer();
            //timer.Tick += new EventHandler(timer_Tick); // Everytime timer ticks, timer_Tick will be called
            //timer.Interval = (1000) * (1);              // Timer will tick evert second
            //timer.Enabled = true;                       // Enable the timer
            



            //try
            //{
            ////    System.Net.Sockets.Socket sock = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
            //    //sock.ReceiveTimeout = 2000;
            //    //sock.SendTimeout = 2000;
            //    sock.Connect(ipa, port);
            //    timeout = 0;
            //    timer.Start();                              // Start the timer

            //    if (sock.Connected == true)  // Port is in use and connection is successful
            //        up = true;

            //    sock.Close();
            //}
            //catch (System.Net.Sockets.SocketException ex)
            //{
            //    if (ex.ErrorCode == 10061)  // Port is unused and could not establish connection 
            //        up = true;
            //    else
            //        up = false;
            //}
                using (TcpClient tcp = new TcpClient())
                {
                    
                    IAsyncResult ar = tcp.BeginConnect(hostname, port, null, null);
                    System.Threading.WaitHandle wh = ar.AsyncWaitHandle;
                    Thread.Sleep(500);
                    try
                    {
                        if (tcp.Connected)
                        {
                            up = true;
                            tcp.Close();
                            return up;
                        }
                        if (!ar.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5), false))
                        {
                            tcp.Close();

                        }
                        try
                        {
                            tcp.EndConnect(ar);
                        }
                        catch
                        { }
                    }
                    //finally
                    //{
                    //    wh.Close();
                    //}
                    catch (System.Net.Sockets.SocketException ex)
                    {
                        if (ex.ErrorCode == 10061)  // Port is unused and could not establish connection 
                                up = true;
                        else
                                up = false;
                    }
                    wh.Close();
                }
            return up;
        }

        #region old thread garbage?

        private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            t = new Thread(scan_done);
            t.IsBackground = true;
            t.Start();
        }

        private void scan_done()
        {
            bool flip = true;
            for (int i = 0; i < ScanThread.Length; i++)
            {
                if (ScanThread[i].ThreadState != System.Threading.ThreadState.Stopped)
                {
                    if (!(time.Enabled))
                    {
                        //time.AutoReset = true;
                        time.Elapsed += new ElapsedEventHandler(time_Elapsed);
                        time.Enabled = true;
                        time.Start();
                    }
                    flip = false;
                    //need to check back every 100ms or so
                    break;
                }
            }
            if (flip)
            {
                if (time.Enabled)
                    time.Stop();
                this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe));
                this.demoThread.Start();
                

                if (bscanning)
                    MessageBox.Show("Scan complete!");
                this.bscanning = false;
                this.exported = false;
                _bw.Dispose();
                if (t.IsAlive)
                    t.Abort();
                if (demoThread.IsAlive)
                    demoThread.Abort();
            }
        }

        private void setTextSafeBtn_Click(
            object sender,
            EventArgs e)
        {
            this.demoThread =
                new Thread(new ThreadStart(this.ThreadProcSafe));

            this.demoThread.Start();
        }

        private void ThreadProcSafe()
        {
            this.SetText("Start Scan");
        }

        private void SetText(string text)
        {
        //    // InvokeRequired required compares the thread ID of the
        //    // calling thread to the thread ID of the creating thread.
        //    // If these threads are different, it returns true.
        //    if (this.newScanbtn0.InvokeRequired)
        //    {
        //        SetTextCallback d = new SetTextCallback(SetText);
        //        this.Invoke(d, new object[] { text });
        //    }
        //    else
        //    {
        //        //this.newScanbtn0.Text = text;
        //        this.newScanbtn0.BackgroundImage = Properties.Resources.Add;
        //        ToolTip tool = new ToolTip();
        //        tool.SetToolTip(this.newScanbtn0, "Start Scan");
        //    }
        }

        private void SetGroupBox(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.groupBox1.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.groupBox1.Text = text;
            }
        }

        public void DoSomethingWithThisTree(Color color)
        {
            // Assuming that 'this' points to a TreeView
            if (this.InvokeRequired) this.Invoke(new TreeActionDelegate(DoSomethingWithThisTree),
                new object[] { color });
            else
            {
                treeView1.Nodes[0].ForeColor = Color.OrangeRed;
            }
        }

        void time_Elapsed(object sender, ElapsedEventArgs e)
        {
            scan_done();
            //throw new NotImplementedException();
        }

        private void SetTextBox(RichTextBox rtb)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.richTextBox1.InvokeRequired)
            {
                SetTextCallback2 d = new SetTextCallback2(SetTextBox);
                this.Invoke(d, new object[] { this.richTextBox1.Text });
            }
            else
            {
                rtb = this.richTextBox1;
            }
        }

        public void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            nThreadCount = Convert.ToInt32(targets.Count);

            ScanThread = new System.Threading.Thread[nThreadCount]; // sets array size to nThreadCount
            container cont = new container();
            //cont.ipaddr = tCurrip;
            cont.username = user1;
            cont.password = pass1;
            cont.qfe_scan = qfe_scan;
            cont.misc_scan = misc_scan;
            cont.installpkg_scan = installpkg_scan;
            cont.tree = treeView1;
            cont.reader = readData;
            //richTextBox1.BeginInvoke(new SetTextCallback2(SetTextBox)); 
            //SetTextBox(cont.rtb);
            //cont.rtb = richTextBox1;

            

            for (int lPtr = 0; lPtr < targets.Count; lPtr++)
            {
                //_rw.EnterWriteLock();
                cont.ipaddr = targets[lPtr].name;
                
                ScanThread[lPtr] = new System.Threading.Thread(cont.RunThread);
                ScanThread[lPtr].Name = "Thread " + lPtr;
                ScanThread[lPtr].IsBackground = true;
                ScanThread[lPtr].Start();
                readData = "Starting scan against: " + targets[lPtr].name;
                LogTextEvent(richTextBox1, Color.Black, readData);
                //_rw.ExitWriteLock();
                
                System.Threading.Thread.Sleep(200);
            }
            System.Threading.Thread.Sleep(200);
        }

        private delegate void SetControlPropertyThreadSafeDelegate(Control control, string propertyName, object propertyValue);

        public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
        {
            if (control.InvokeRequired)
            {
                control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
            }
            else
            {
                control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
            }
        }

        private void ScanIP(string tCurrip)
        {
            //nCurrPort = nStartPort;
            nThreadCount = Convert.ToInt32(targets.Count);

            ScanThread = new System.Threading.Thread[nThreadCount]; // sets array size to nThreadCount
            container cont = new container();
            cont.ipaddr = tCurrip;
            cont.username = user1;
            cont.password = pass1;
            cont.qfe_scan = qfe_scan;
            cont.misc_scan = misc_scan;
            cont.installpkg_scan = installpkg_scan;


            for (int lPtr = 0; lPtr <= (ScanThread.Length - 1); lPtr++)
            {
                ScanThread[lPtr] = new System.Threading.Thread(cont.RunThread);
                ScanThread[lPtr].Name = "Thread " + lPtr;
                ScanThread[lPtr].IsBackground = true;
                readData = "Starting scan against: " + tCurrip;
                LogTextEvent(richTextBox1, Color.Black, readData);
                ScanThread[lPtr].Start();
                //this.Text = "Active Threads [" + (lPtr + 1) + "] Scanning : " + tCurrip;
            } //end for

            System.Threading.Thread.Sleep(200);
            
        }
        #endregion

        #endregion

        #region Writers
        private void write_XML(string filename)
        {
            //xml_file = string.Format("Scan-{0:yyyy-MM-dd_hh-mm-ss-tt}.xml",DateTime.Now);
            using (XmlWriter writer = XmlWriter.Create(filename))
            {
                /* *************
                 * <xml>
                 *  <AppScan Date= yyy...  TotalHost=xx>
                 *      <172.15.11.0>
                 *          <172.15.11.1>
                 *              <Application A>
                 *                  <info/>
                 *              <Application B>
                 *                  <info/>
                 *          </172.15.11.1>
                 *      </172.15.11.0>
                 *  </AppScan>
                 * *************/
                writer.WriteStartDocument();
                writer.WriteStartElement("AppScan");        //APPSCAN
                writer.WriteAttributeString("Date",string.Format("{0:yyyy-MM-dd_hh-mm-ss-tt}", DateTime.Now));
                writer.WriteAttributeString("TotalHosts", targets.Count.ToString());

                string class_C = null;
                var result = from item in targets orderby item.name descending select item;
                //List<TreeItem> tree = new List<TreeItem>();
                List<Targets> temp = result.ToList();
                //TreeItem itz;
                if (temp[0].name.Contains('.'))
                {
                   class_C = temp[0].name.Split('.')[0] + "." +  temp[0].name.Split('.')[1] + "." + temp[0].name.Split('.')[2] + ".";
                    writer.WriteStartElement("Network");
                    writer.WriteAttributeString("ClassC", class_C + "0");//172.15.11.0
                }
                for (int i = 0; i < temp.Count;i++ )
                {
                    if (temp[i].name.Contains(class_C))
                    {
                    
                        writer.WriteStartElement("Host");           //172.15.11.1
                        writer.WriteAttributeString("IPaddr", temp[i].name);
                        if (installpkg_scan)
                        {
                            for (int k = 0; k < temp[i].appitemz.Count; k++)
                            {
                                writer.WriteStartElement("Application");
                                writer.WriteAttributeString("Name", temp[i].appitemz[k].name); //Application A
                                /******
                                 * May implement reflection here later, but this is simple and works
                                 * 
                                 * ****/
                                Type t = temp[i].appitemz[k].GetType();

                                // Cycle through the properties.
                                foreach (PropertyInfo p in t.GetProperties())
                                {
                                    // Write the name and the value.
                                    if (p.Name == "name" || string.IsNullOrEmpty(p.GetValue(temp[i].appitemz[k], null).ToString()) == true)
                                    {
                                        writer.WriteElementString(p.Name, "");
                                    }
                                    else
                                    {
                                        writer.WriteElementString(p.Name, p.GetValue(temp[i].appitemz[k], null).ToString());
                                    }
                                }
                                writer.WriteEndElement();  // close Application
                            }
                        }
                        if (qfe_scan)
                        {
                            for (int k = 0; k < temp[i].wup.Count; k++)
                            {
                                writer.WriteStartElement("QuickFixEngineering");
                                writer.WriteAttributeString("Name", temp[i].wup[k].Name); //Application A
                                /******
                                 * May implement reflection here later, but this is simple and works
                                 * 
                                 * ****/
                                Type t = temp[i].wup[k].GetType();

                                // Cycle through the properties.
                                foreach (PropertyInfo p in t.GetProperties())
                                {
                                    // Write the name and the value.
                                    if (p.Name == "name" || string.IsNullOrEmpty(p.GetValue(temp[i].wup[k], null).ToString()) == true)
                                    {
                                        writer.WriteElementString(p.Name, "");
                                    }
                                    else
                                    {
                                        writer.WriteElementString(p.Name, p.GetValue(temp[i].wup[k], null).ToString());
                                    }
                                }
                                writer.WriteEndElement();  // close QFE
                            }
                        }
                        if (misc_scan)
                        {
                            for (int k = 0; k < temp[i].OS.Count; k++)
                            {
                                writer.WriteStartElement("OperatingSystem");
                                writer.WriteAttributeString("Name", temp[i].OS[k].Name); //Application A
                                /******
                                 * May implement reflection here later, but this is simple and works
                                 * 
                                 * ****/
                                Type t = temp[i].OS[k].GetType();

                                // Cycle through the properties.
                                foreach (PropertyInfo p in t.GetProperties())
                                {
                                    // Write the name and the value.
                                    if (p.Name == "name" || string.IsNullOrEmpty(p.GetValue(temp[i].OS[k], null).ToString()) == true)
                                    {
                                        writer.WriteElementString(p.Name, "");
                                    }
                                    else
                                    {
                                        writer.WriteElementString(p.Name, p.GetValue(temp[i].OS[k], null).ToString());
                                    }
                                }
                                writer.WriteEndElement();  // close OS
                            }
                        }
                        writer.WriteEndElement(); //close 172.15.11.1
                    }
                    else
                    {
                        writer.WriteEndElement(); //close 172.15.11.0
                        class_C = temp[i].name.Split('.')[0] + "." + temp[i].name.Split('.')[1] + "." + temp[i].name.Split('.')[2] + ".";
                        writer.WriteStartElement("Network");
                        writer.WriteAttributeString("ClassC", class_C + "0");//172.18.11.0

                        //writer.WriteStartElement(temp[i].name);           //172.18.11.2

                        writer.WriteStartElement("Host");           //172.18.11.1
                        writer.WriteAttributeString("IPaddr", temp[i].name);
                        if (installpkg_scan)
                        {
                            for (int k = 0; k < temp[i].appitemz.Count; k++)
                            {
                                writer.WriteStartElement("Application");
                                writer.WriteAttributeString("Name", temp[i].appitemz[k].name); //Application A
                                /******
                                 * May implement reflection here later, but this is simple and works
                                 * 
                                 * ****/
                                Type t = temp[i].appitemz[k].GetType();

                                // Cycle through the properties.
                                foreach (PropertyInfo p in t.GetProperties())
                                {
                                    // Write the name and the value.
                                    if (p.Name == "name" || string.IsNullOrEmpty(p.GetValue(temp[i].appitemz[k], null).ToString()) == true)
                                    {
                                        writer.WriteElementString(p.Name, "");
                                    }
                                    else
                                    {
                                        writer.WriteElementString(p.Name, p.GetValue(temp[i].appitemz[k], null).ToString());
                                    }
                                }
                                writer.WriteEndElement();  // close Application
                            }
                        }
                        if (qfe_scan)
                        {
                            for (int k = 0; k < temp[i].wup.Count; k++)
                            {
                                writer.WriteStartElement("QuickFixEngineering");
                                writer.WriteAttributeString("Name", temp[i].wup[k].Name); //Application A
                                /******
                                 * May implement reflection here later, but this is simple and works
                                 * 
                                 * ****/
                                Type t = temp[i].wup[k].GetType();

                                // Cycle through the properties.
                                foreach (PropertyInfo p in t.GetProperties())
                                {
                                    // Write the name and the value.
                                    if (p.Name == "name" || string.IsNullOrEmpty(p.GetValue(temp[i].wup[k], null).ToString()) == true)
                                    {
                                        writer.WriteElementString(p.Name, "");
                                    }
                                    else
                                    {
                                        writer.WriteElementString(p.Name, p.GetValue(temp[i].wup[k], null).ToString());
                                    }
                                }
                                writer.WriteEndElement();  // close QFE
                            }
                        }
                        if (misc_scan)
                        {
                            for (int k = 0; k < temp[i].OS.Count; k++)
                            {
                                writer.WriteStartElement("OperatingSystem");
                                writer.WriteAttributeString("Name", temp[i].OS[k].Name); //Application A
                                /******
                                 * May implement reflection here later, but this is simple and works
                                 * 
                                 * ****/
                                Type t = temp[i].OS[k].GetType();

                                // Cycle through the properties.
                                foreach (PropertyInfo p in t.GetProperties())
                                {
                                    // Write the name and the value.
                                    if (p.Name == "name" || string.IsNullOrEmpty(p.GetValue(temp[i].OS[k], null).ToString()) == true)
                                    {
                                        writer.WriteElementString(p.Name, "");
                                    }
                                    else
                                    {
                                        writer.WriteElementString(p.Name, p.GetValue(temp[i].OS[k], null).ToString());
                                    }
                                }
                                writer.WriteEndElement();  // close OS
                            }
                        }
                        //for (int k = 0; k < temp[i].appitemz.Count; k++)
                        //{
                        //    writer.WriteStartElement("Application");
                        //    writer.WriteAttributeString("Name", temp[i].appitemz[k].name); //Application A
                        //    /******
                        //     * May implement reflection here later, but this is simple and works
                        //     * 
                        //     * ****/
                        //    writer.WriteElementString("AssignmentType", temp[i].appitemz[k].assign_type.ToString());
                        //    writer.WriteElementString("Caption", temp[i].appitemz[k].caption.ToString());
                        //    writer.WriteElementString("Desc", temp[i].appitemz[k].description.ToString());
                        //    writer.WriteElementString("HelpLink", temp[i].appitemz[k].helplink.ToString());
                        //    writer.WriteElementString("HelpTele", temp[i].appitemz[k].helptele.ToString());
                        //    writer.WriteElementString("ID_num", temp[i].appitemz[k].id_num.ToString());
                        //    writer.WriteElementString("InstallDate", temp[i].appitemz[k].install_date.ToString());
                        //    writer.WriteElementString("InstallDate2", temp[i].appitemz[k].install_date_2.ToString());
                        //    writer.WriteElementString("InstallLoc", temp[i].appitemz[k].install_loc.ToString());
                        //    writer.WriteElementString("InstallSource", temp[i].appitemz[k].install_source.ToString());
                        //    writer.WriteElementString("Install_state", temp[i].appitemz[k].install_state.ToString());
                        //    writer.WriteElementString("Language", temp[i].appitemz[k].language.ToString());
                        //    writer.WriteElementString("LocalPackage", temp[i].appitemz[k].localPkg.ToString());
                        //    writer.WriteElementString("PackageName", temp[i].appitemz[k].pkgname.ToString());
                        //    writer.WriteElementString("ProductID", temp[i].appitemz[k].productID.ToString());
                        //    writer.WriteElementString("RegCompany", temp[i].appitemz[k].reg_co.ToString());
                        //    writer.WriteElementString("RegOwner", temp[i].appitemz[k].regowner.ToString());
                        //    writer.WriteElementString("SKUNumber", temp[i].appitemz[k].sku.ToString());
                        //    writer.WriteElementString("URLAboutInfo", temp[i].appitemz[k].url_about.ToString());
                        //    writer.WriteElementString("URLUpdateInfo", temp[i].appitemz[k].url_update.ToString());
                        //    writer.WriteElementString("Vendor", temp[i].appitemz[k].vendor.ToString());
                        //    writer.WriteElementString("Version", temp[i].appitemz[k].version.ToString());
                        //    writer.WriteEndElement();  // close Application
                        //}
                        writer.WriteEndElement(); //close 172.15.11.1
                        
                    }
                }
                writer.WriteEndElement(); // close class C
                writer.WriteEndElement(); //close root
                writer.WriteEndDocument(); //close document
            }
        }

        private void write_csv_new(string filename, int number)
        {
            StreamWriter wR = new StreamWriter(filename);

            Type t = targets[0].appitemz[0].GetType();
            wR.Write("," + "ApplicationName");
            foreach (PropertyInfo p in t.GetProperties())
            {
                if (p.Name.ToLower() != "name")
                    wR.Write("," + p.Name);
            }
            wR.Write("\n");

            foreach (var foo in targets)
            {
                for (int k = 0; k < foo.appitemz.Count; k++)
                {
                    //*******
                    // Host, ...
                    // 10.0.2.15, 
                    //
                    //***********
                    wR.Write(foo.name);
                    t = foo.appitemz[k].GetType();
                    wR.Write("," + foo.appitemz[k].Name);
                    foreach (PropertyInfo p in t.GetProperties())
                    {
                        if (p.Name.ToLower() != "name")
                        {
                            if (string.IsNullOrEmpty(p.GetValue(foo.appitemz[k], null).ToString()) == true)
                            {
                                wR.Write(",");
                            }
                            else
                            {
                                wR.Write("," + p.GetValue(foo.appitemz[k], null).ToString());
                            }
                        }
                    }
                    wR.Write("\n");
                }
            }
        }

        private void write_csv(string filename)
        {
            /********
             * TODO:
             * 
             * Can we multi-thread this?
             * 
             * *******///
            //string filename = string.Format(prefix + "-{0:yyyy-MM-dd_hh-mm-ss-tt}.csv", DateTime.Now);
            string[] inserted = filename.Split('.');
            StreamWriter wP = new StreamWriter(inserted[0] + "_packages_." + inserted[1]);
            wP.Write("Host");
            if (targets[0].appitemz.Count > 0)
            {
                Type t = targets[0].appitemz[0].GetType();
                wP.Write("," + "ApplicationName");
                foreach (PropertyInfo p in t.GetProperties())
                {
                    if (p.Name.ToLower() != "name")
                        wP.Write("," + p.Name);
                }
                wP.Write("\n");
            }


            StreamWriter wQ = new StreamWriter(inserted[0] + "_QFE_." + inserted[1]);
            wQ.Write("Host");
            if (targets[0].wup.Count > 0)
            {
                //wP.Write("Host");
                Type t = targets[0].wup[0].GetType();
                wQ.Write("," + "Name");
                foreach (PropertyInfo p in t.GetProperties())
                {
                    if (p.Name.ToLower() != "name")
                        wQ.Write("," + p.Name);
                }
                wQ.Write("\n");
            }

            StreamWriter wM = new StreamWriter(inserted[0] + "_MISC_." + inserted[1]);
            wM.Write("Host");
            if (targets[0].OS.Count > 0)
            {
            Type t = targets[0].OS[0].GetType();
            wM.Write("," + "Name");
            foreach (PropertyInfo p in t.GetProperties())
            {
                if (p.Name.ToLower() != "name")
                    wM.Write("," + p.Name);
            }
            wM.Write("\n");
            }



            StreamWriter wR = new StreamWriter(inserted[0] + "_reg_." + inserted[1]);
            wR.Write("Host");
            if (targets[0].r1.Count > 0)
            {
            Type t = targets[0].r1[0].GetType();
           //wR.Write("," + "Name");
            foreach (PropertyInfo p in t.GetProperties())
            {
                if (p.Name.ToLower() != "name")
                    wR.Write("," + p.Name);
            }
            wR.Write("\n");
            }

            foreach (var foo in targets)
            {
                if (installpkg_scan)
                {
                    for (int k = 0; k < foo.appitemz.Count; k++)
                    {
                        //*******
                        // Host, ...
                        // 10.0.2.15, 
                        //
                        //***********
                        wP.Write(foo.name);
                        Type t = foo.appitemz[k].GetType();
                        wP.Write("," + foo.appitemz[k].Name);
                        foreach (PropertyInfo p in t.GetProperties())
                        {
                            if (p.Name.ToLower() != "name")
                            {
                                if (string.IsNullOrEmpty(p.GetValue(foo.appitemz[k], null).ToString()) == true)
                                {
                                    wP.Write(",");
                                }
                                else
                                {
                                    if (p.GetValue(foo.appitemz[k], null).ToString().Contains(','))
                                        p.SetValue(foo.appitemz[k], p.GetValue(foo.appitemz[k], null).ToString().Replace(',', ' '), null);
                                    wP.Write("," + p.GetValue(foo.appitemz[k], null).ToString());
                                }
                            }
                        }
                        wP.Write("\n");
                    }
                }
                if (qfe_scan)
                {
                    for (int k = 0; k < foo.wup.Count; k++)
                    {
                        //*******
                        // Host, ...
                        // 10.0.2.15, 
                        //
                        //***********
                        wQ.Write(foo.name);
                        Type t = foo.wup[k].GetType();
                        wQ.Write("," + foo.wup[k].Name);
                        foreach (PropertyInfo p in t.GetProperties())
                        {
                            if (p.Name.ToLower() != "name")
                            {
                                if (string.IsNullOrEmpty(p.GetValue(foo.wup[k], null).ToString()) == true)
                                {
                                    wQ.Write(",");
                                }
                                else
                                {
                                    if (p.GetValue(foo.wup[k], null).ToString().Contains(','))
                                        p.SetValue(foo.wup[k], p.GetValue(foo.wup[k], null).ToString().Replace(',', ' '), null);
                                    wQ.Write("," + p.GetValue(foo.wup[k], null).ToString());
                                }
                            }
                        }
                        wQ.Write("\n");
                    }
                }
                if (misc_scan)
                {
                    for (int k = 0; k < foo.OS.Count; k++)
                    {
                        //*******
                        // Host, ...
                        // 10.0.2.15, 
                        //
                        //***********
                        wM.Write(foo.name);
                       
                        Type t = foo.OS[k].GetType();
                        wM.Write("," + foo.OS[k].Name);
                        foreach (PropertyInfo p in t.GetProperties())
                        {
                            if (p.Name.ToLower() != "name")
                            {
                                if (string.IsNullOrEmpty(p.GetValue(foo.OS[k], null).ToString()) == true)
                                {
                                    wM.Write(",");
                                }
                                else
                                {
                                    if (p.GetValue(foo.OS[k], null).ToString().Contains(','))
                                        p.SetValue(foo.OS[k], p.GetValue(foo.OS[k], null).ToString().Replace(',', ' '), null);
                                    wM.Write("," + p.GetValue(foo.OS[k], null).ToString());
                                }
                            }
                        }
                        wM.Write("\n");
                    }
                }
                if (reg_scan)
                {
                    for (int k = 0; k < foo.r1.Count; k++)
                    {
                        //*******
                        // Host, ...
                        // 10.0.2.15, 
                        //
                        //***********
                        wR.Write(foo.name);
                       
                        Type t = foo.r1[k].GetType();
                        wR.Write("," + foo.r1[k].DisplayName);
                        foreach (PropertyInfo p in t.GetProperties())
                        {
                            if (p.Name.ToLower() != "displayname")
                            {
                                if (string.IsNullOrEmpty(p.GetValue(foo.r1[k], null).ToString()) == true)
                                {
                                    wR.Write(",");
                                }
                                else
                                {
                                    if (p.GetValue(foo.r1[k], null).ToString().Contains(','))
                                        p.SetValue(foo.r1[k], p.GetValue(foo.r1[k], null).ToString().Replace(',', ' '), null);
                                    wR.Write("," + p.GetValue(foo.r1[k], null).ToString());
                                }
                            }
                        }
                        wR.Write("\n");
                    }
                }
            }
            wR.Flush();
            Thread.Sleep(300);
            wR.Close();
            wR.Dispose();
            //MessageBox.Show("Scan exported to " + filename + " successfully!");
        }
        #endregion
        private bool get_credentials(string machine)
        {
            credentials c_box = new credentials();
            c_box.mach_text = "SSH scan requires re-entry of credentials for " + machine;
            c_box.ShowDialog(new Form());

            if (c_box.DialogResult == DialogResult.OK)
            {
                username = c_box.User;
                password = c_box.PWD;

                return true;
            }
            else
            {
                return false;
            }
        }

        #region WMI stuff
        public void useWMI_installedapps(string remoteHostName, string userName, string password) //, TreeView tree, bool qf_scan, bool misc)
        {
            string remoteIP = string.Empty;

            try
            {

            Begin:
                ApplicationsList itemsList = new ApplicationsList(remoteHostName, userName, password);

                if (itemsList.ErrorMessage.ToLower().Contains("local connections")) // || itemsList.ErrorMessage.ToLower().Contains("fall within the expected range"))
                {
                    //_rw.EnterWriteLock();
                    remoteIP = remoteHostName;
                    remoteHostName = "localhost";
                    //readData = "An error has occurred, trying again...";
                    //_rw.ExitWriteLock();
                    LogTextEvent(richTextBox1, Color.OrangeRed, "Trying localhost workaround...");
                    goto Begin;
                }
                else
                {
                    if (itemsList.ErrorMessage.Length > 0)
                    {
                        LogTextEvent(richTextBox1, Color.Red, "ERROR: " + itemsList.ErrorMessage);
                        
                        host = remoteHostName;
                        if (remoteHostName == "localhost")
                            host = remoteIP;
                        tree_color(host, true, itemsList.ErrorMessage.ToString());
                        int ndx = targets.FindIndex(FindTarget);
                        tree_color(host, Color.Gray);
                        targets[ndx].killswitch = true;
                    }
                }

                if (itemsList.Count > 0)
                {
                    //_rw.EnterWriteLock();
                    host = remoteHostName;
                    if (remoteHostName == "localhost")
                        host = remoteIP;
                    int ndx = targets.FindIndex(FindTarget);
                    targets[ndx].SetAppz(itemsList);

                    for (int i = 0; i < treeView1.Nodes[0].Nodes.Count; i++)
                    {
                        string[] classC = treeView1.Nodes[0].Nodes[i].Text.Split('.');
                        if (host.Contains(classC[0] + "." + classC[1] + "." + classC[2] + "."))
                        {
                            for (int j = 0; j < treeView1.Nodes[0].Nodes[i].Nodes.Count; j++)
                            {
                                if (treeView1.Nodes[0].Nodes[i].Nodes[j].Text == host)
                                {

                                    if (!(misc_scan) && !(qfe_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Green;
                                    }
                                    if ((misc_scan) && !(qfe_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Green;
                                    }
                                    if ((misc_scan) && (qfe_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Orange;
                                    }
                                    if (!(misc_scan) && (qfe_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Orange;
                                    }

                                    break;
                                }
                            }
                            break;
                        }
                    }
                    //_rw.ExitWriteLock();

                }
            }
            catch (Exception e)
            {
                //MessageBox.Show("There was an error trying to query: " + remoteHostName + ".\n The details can be found below: " + e.ToString());
                if (!(e.ToString().ToLower().Contains("thread")))
                    MessageBox.Show("There was an error attempting to use WMI to retrieve applications.\nThis is usually due to invalid credentials.\n" + e.ToString());
            }
        }

        public void useWMI_misc(string remoteHostName, string userName, string password) //, TreeView tree, bool ins_scan, bool qf_scan, RichTextBox rtb)
        {
            string remoteIP = string.Empty;

            try
            {
            Begin:
                OSList.OSList itemsList = new OSList.OSList(remoteHostName, userName, password);

                if (itemsList.ErrorMessage.ToLower().Contains("local connections")) // || itemsList.ErrorMessage.ToLower().Contains("fall within the expected range"))
                {
                    //_rw.EnterWriteLock();
                    remoteIP = remoteHostName;
                    remoteHostName = "localhost";
                    //_rw.ExitWriteLock();
                    LogTextEvent(richTextBox1, Color.OrangeRed, "Trying localhost workaround...");
                    goto Begin;
                }
                else
                {
                    if (itemsList.ErrorMessage.Length > 0)
                    {
                        readData = "ERROR: " + itemsList.ErrorMessage;
                        LogTextEvent(richTextBox1, Color.Red, readData);

                        host = remoteHostName;
                        if (remoteHostName == "localhost")
                            host = remoteIP;
                        tree_color(host, true, itemsList.ErrorMessage.ToString());
                        int ndx = targets.FindIndex(FindTarget);
                        tree_color(host, Color.Gray);
                        targets[ndx].killswitch = true;
                    }
                }

                if (itemsList.Count > 0)
                {
                    //_rw.EnterWriteLock();
                    host = remoteHostName;
                    if (remoteHostName == "localhost")
                        host = remoteIP;
                    int ndx = targets.FindIndex(FindTarget);
                    targets[ndx].SetAppz(itemsList);
                    for (int i = 0; i < treeView1.Nodes[0].Nodes.Count; i++)
                    {
                        string[] classC = treeView1.Nodes[0].Nodes[i].Text.Split('.');
                        if (host.Contains(classC[0] + "." + classC[1] + "." + classC[2] + "."))
                        {
                            for (int j = 0; j < treeView1.Nodes[0].Nodes[i].Nodes.Count; j++)
                            {
                                if (treeView1.Nodes[0].Nodes[i].Nodes[j].Text == host)
                                {
                            
                                        if (!(installpkg_scan) && !(qfe_scan))
                                        {
                                            treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Green;
                                        }
                                        if ((installpkg_scan) && !(qfe_scan))
                                        {
                                            treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.LightGoldenrodYellow;
                                        }
                                        if ((installpkg_scan) && (qfe_scan))
                                        {
                                            treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Orange;
                                        }
                                        if (!(installpkg_scan) && (qfe_scan))
                                        {
                                            treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.LightGoldenrodYellow;
                                        }

                                    break;
                                }
                            }
                            break;
                        }
                    }
                    //_rw.ExitWriteLock();
                }
            }
            catch (Exception e)
            {
                if (!(e.ToString().ToLower().Contains("thread")))
                    MessageBox.Show("There was an error attempting to use WMI to retrieve applications.\nThis is usually due to invalid credentials.\n" + e.ToString());
            }
        }
        public void useWMI_qfe(string remoteHostName, string userName, string password) //, TreeView tree, bool ins_scan, bool misc)
        {
            string remoteIP = string.Empty;

            try
            {
            Begin:
                UpdateList.UpdateList itemsList = new UpdateList.UpdateList(remoteHostName, userName, password);

                if (itemsList.ErrorMessage.ToLower().Contains("local connections")) // || itemsList.ErrorMessage.ToLower().Contains("fall within the expected range"))
                {
                    //_rw.EnterWriteLock();
                    remoteIP = remoteHostName;
                    remoteHostName = "localhost";
                    //_rw.ExitWriteLock();
                    LogTextEvent(richTextBox1, Color.OrangeRed, "Trying localhost workaround...");
                    goto Begin;
                }
                else
                {
                    if (itemsList.ErrorMessage.Length > 0)
                    {
                        readData = "ERROR: " + itemsList.ErrorMessage;
                        LogTextEvent(richTextBox1, Color.Red, readData);

                        host = remoteHostName;
                        if (remoteHostName == "localhost")
                            host = remoteIP;
                        tree_color(host, true, itemsList.ErrorMessage.ToString());
                        int ndx = targets.FindIndex(FindTarget);
                        tree_color(host, Color.Gray);
                        targets[ndx].killswitch = true;
                    }
                }

                //   if (itemsList.ErrorMessage.Length == 0)
                //   {
                // StreamWriter sW = new StreamWriter(filename, false);
                if (itemsList.Count > 0)
                {
                    //_rw.EnterWriteLock();
                    host = remoteHostName;
                    if (remoteHostName == "localhost")
                        host = remoteIP;
                    int ndx = targets.FindIndex(FindTarget);
                    targets[ndx].SetAppz(itemsList);
                    for (int i = 0; i < treeView1.Nodes[0].Nodes.Count; i++)
                    {
                        string[] classC = treeView1.Nodes[0].Nodes[i].Text.Split('.');
                        if (host.Contains(classC[0] + "." + classC[1] + "." + classC[2] + "."))
                        {
                            for (int j = 0; j < treeView1.Nodes[0].Nodes[i].Nodes.Count; j++)
                            {
                                if (treeView1.Nodes[0].Nodes[i].Nodes[j].Text == host)
                                {

                                    if (!(installpkg_scan) && !(misc_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Green;
                                    }
                                    if ((installpkg_scan) && !(misc_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Green;
                                    }
                                    if ((installpkg_scan) && (misc_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Green;
                                    }
                                    if (!(installpkg_scan) && (misc_scan))
                                    {
                                        treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = Color.Green;
                                    }

                                    break;
                                }
                            }
                            break;
                        }
                    }
                    //_rw.ExitWriteLock();

                }
            }
            catch (Exception e)
            {
                //MessageBox.Show("There was an error trying to query: " + remoteHostName + ".\n The details can be found below: " + e.ToString());
                if (!(e.ToString().ToLower().Contains("thread")))
                    MessageBox.Show("There was an error attempting to use WMI to retrieve applications.\nThis is usually due to invalid credentials.\n" + e.ToString());
            }
        }

        private void FindRecursive(TreeNode treeNode, string name)
        {
            foreach (TreeNode tn in treeNode.Nodes)
            {
                // if the text properties match, color the item
                if (tn.Text == name)
                    tn.ForeColor = Color.OrangeRed;

                FindRecursive(tn, name);
            }
        }
        public void useWMIC(string host, string user, string pass, string[] opts)
        {
            string opt = string.Empty;
            string args = "/NODE:"+host+" /USER:"+user+" /PASSWORD:"+pass;
            if (opts.Length>0)
            {   
                    foreach (string s in opts)
                    {
                        opt = opt + " " + s;
                    }
            }
            args = args + " " + opt;
            bool attempt = true;
            RETRY:
            int exit = run_wmic(args, host);

            if (exit != 0)
            {
                if (attempt == true)
                {
                    args = "/NODE:" + host + " " + opt;
                    attempt = false;
                    goto RETRY;
                }
            }
        }

        private void useREG(string remoteHostName, string userName, string password, string key)
        {
        //    //registry regg = new registry(remoteHostName, userName, password, key);
        //    bool reconnect = true;
        //AGAIN:
        //    //string[] keyz = regg.WMI_readreg(remoteHostName, userName, password, key);
        //    //string[] keyz = regg.do_regread(remoteHostName, key);
        //    if (keyz[0] != "BAADF00D")
        //    {
        //        foreach (string k in keyz)
        //            System.Diagnostics.Debug.WriteLine(k);
        //    }
        //    else
        //    {
        //        if (keyz[0] == "BAADF00D" && reconnect == true)
        //        {
        //            remoteHostName = "localhost";
        //            reconnect = false;
        //            goto AGAIN;
        //        }
        //    }
        }
        #endregion

        private static bool FindTarget(Targets t1)
        {
            string given = host;
            if (t1.name==given )
            {
                return true;
            }
            {
                return false;
            }
        }

        private void clear_dgv()
        {
            if (application_dgv.Rows.Count > 0)
            {
                if (this.application_dgv.DataSource != null)
                {
                    this.application_dgv.DataSource = null;
                }
                else
                {
                    this.application_dgv.Rows.Clear();
                }
            }

            if ( qfe_dgv.Rows.Count > 0)
            {
                if (this.qfe_dgv.DataSource != null)
                {
                    this.qfe_dgv.DataSource = null;
                }
                else
                {
                    this.qfe_dgv.Rows.Clear();
                }
            }
            if (dataGridView1.Rows.Count > 0)
            {
                if (this.dataGridView1.DataSource != null)
                {
                    this.dataGridView1.DataSource = null;
                }
                else
                {
                    this.dataGridView1.Rows.Clear();
                }
            }
            if (registrydgv.Rows.Count > 0)
            {
                if (this.registrydgv.DataSource != null)
                {
                    this.registrydgv.DataSource = null;
                }
                else
                {
                    this.registrydgv.Rows.Clear();
                }
            }
                
        }

        #region tree_stuff
        private void fill_tree()
        {
            try
            {
                treeView1.Nodes.Clear();
                //get nodes from Scan Wizard 
                /*******************************
                 *  10.0.2.0
                 *      10.0.2.2
                 *      10.0.2.15
                 *      and so on.  It needs to be sorted 
                 *      and we need to extract the class
                 *      C network address out.
                 * *****************************/
                string class_C = null;
                var result = from item in targets orderby item.name ascending select item;
                List<TreeItem> tree = new List<TreeItem>();
                List<Targets> temp = result.ToList();
                TreeItem itz;

                bool ip = IPAddress.TryParse(temp[0].name, out temp[0].ipaddr);

                if (ip)
                {
                   
                    if (!(String.IsNullOrEmpty(temp[0].ipaddr.ToString())))
                    {
                        if (temp[0].name.Contains('.'))
                        {
                            class_C = temp[0].name.Split('.')[0] + "." + temp[0].name.Split('.')[1] + "." + temp[0].name.Split('.')[2] + ".";
                            itz = new TreeItem(class_C + "0", 0);
                            tree.Add(itz);

                            for (int i = 0; i < temp.Count; i++)
                            {

                                //if do not resolve is true skip
                                //else
                                //stub
                                string test = resolver(targets[i].ipaddr.ToString());
                                if (!(String.IsNullOrEmpty(test)))
                                {
                                    temp[i].name = test;
                                }

                                if (!(string.IsNullOrEmpty(temp[i].ipaddr.ToString())))
                                {

                                    if (!(temp[i].ipaddr.ToString().Contains(class_C)))
                                    {
                                        class_C = temp[i].ipaddr.ToString().Split('.')[0] + "." + temp[i].ipaddr.ToString().Split('.')[1] + "." + temp[i].ipaddr.ToString().Split('.')[2] + ".";
                                        itz = new TreeItem(class_C + "0", 0);
                                        tree.Add(itz);      //input into a list
                                    }
                                    itz = new TreeItem(temp[i].ipaddr.ToString(), 1);
                                    tree.Add(itz);      //input into a list
                                    itz = new TreeItem(temp[i].name, 2);
                                    tree.Add(itz);
                                }
                            }
                        }
                        else
                        {
                            //defaults to DOMAIN mode ... not implemented yet
                            if (!(String.IsNullOrEmpty(temp[0].domain.ToString())))
                            {

                            }
                        }
                    }
                    else
                    {
                        //can't parse ip addr, must be a hostname
                        //Probably sort by hostname -- alphabetical ?
                        if (!(String.IsNullOrEmpty(temp[0].domain.ToString())))
                        {

                            string domain = temp[0].domain.ToUpper();
                                itz = new TreeItem(domain, 0);
                                tree.Add(itz);

                                for (int i = 0; i < temp.Count; i++)
                                {
                                    if (!(string.IsNullOrEmpty(temp[i].domain)))
                                    {
                                        if (!(temp[i].domain.Contains(domain)))
                                        {
                                            domain = temp[0].domain.ToUpper();
                                            itz = new TreeItem(domain, 0);
                                            tree.Add(itz);      //input into a list
                                        }
                                        itz = new TreeItem(temp[i].name, 1);
                                        tree.Add(itz);      //input into a list
                                    }
                                }
                            
                        }
                        else
                        {
                            //just go with it for now
                            itz = new TreeItem(temp[0].name, 0);
                            tree.Add(itz);
                        }
                        
                    }
                }
                populate_tree(treeView1, tree);
            }
            catch (Exception ex)
            {
                MessageBox.Show("An error has occured trying to display the hosts.\n Please contact support with the following information: \n" + ex.ToString());
            }
        }

        public static void populate_tree(TreeView tree, ICollection<TreeItem> items)
        {
            //tree.Nodes.Clear();
            List<TreeNode> roots = new List<TreeNode>();
            roots.Add(tree.Nodes.Add("Hosts"));
            //for (int i = 0; i < items.Count; i++)
            //{
            int current_lvl = 0;
            bool childnode = false;
            int i = 0;
            int newlvl = 0;
            int thislvl = 0;
            foreach (TreeItem item in items)
            {

                if (childnode)
                {
                    //do work
                    roots.Add(roots[thislvl].LastNode);
                    newlvl = roots.Count - 1;
                    childnode = false;
                }
                else
                {
                    newlvl = item.Level;
                }
                if (item.Level == roots.Count)
                {
                    roots.Add(roots[roots.Count - 1].LastNode);
                }
                if (current_lvl > item.Level)
                {
                   // roots.Add(roots[roots.Count - 1].LastNode);
                    thislvl = item.Level;
                    childnode = true;
                }
                else
                {

                }
                roots[newlvl].Nodes.Add(item.Name);
                current_lvl = item.Level;
                i++;
            }
            tree.ExpandAll();
        }

        private void get_targets_file(string filename, int max)
        {
                using (StreamReader sR = new StreamReader(filename))
                {
                    string line;
                    while ((line = sR.ReadLine()) != null)
                    {
                        Targets t1 = new Targets();
                        richTextBox1.AppendText("Found host: " + line + "\n");
                        this.Update();
                        t1.name = line;
                        //To tell the truth takes courage that very few will ever have.
                        targets.Add(t1);
                        Console.WriteLine(line);
                    }
                }
        }

        private void get_targets_wizard(string[] arr)
        {
            if (arr.Length > 0)
            {
                foreach (string str in arr)
                {
                    Targets t1 = new Targets();
                    readData = "Importing host: " + str;
                    LogTextEvent(richTextBox1, Color.Black, readData);
                    this.Update();
                    t1.name = str;
                    targets.Add(t1);
                }
            }

        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            //once selected display contents relevant to slected node
            string name = (sender as TreeView).SelectedNode.Text;
            node_select(name);
        }

        private void node_select(string name)
        {
            
            if (name.Contains('.') && (name.Split('.').Length > 3))
            {
                if (name.Split('.')[name.Split('.').Length - 1] == "0")
                {
                    //Summary page
                }
                else
                {
                    int MAX = targets.Count;

                    for (int i = 0; i < MAX; i++)
                    {
                        //if IP mode, yes
                        string hostname = targets[i].ipaddr.ToString();
                        if (hostname == name)
                        {
                            groupBox1.Text = "Details for " + name;
                            clear_dgv();
                            application_dgv.DataSource = targets[i].appitemz;

                            //Quick Fix engineering DGV
                            qfe_dgv.DataSource = targets[i].wup;
                            qfe_dgv.RowHeadersVisible = false;
                            qfe_dgv.AutoResizeColumns();

                            if (targets[i].OS.Count > 0)
                            {
                                for (int k = 0; k < targets[i].OS.Count; k++)
                                {
                                    Type t = targets[i].OS[k].GetType();

                                    // Cycle through the properties.
                                    foreach (PropertyInfo p in t.GetProperties())
                                    {
                                        int n = dataGridView1.Rows.Add();
                                        dataGridView1.Rows[n].Cells[0].Value = p.Name.ToString();
                                        dataGridView1.Rows[n].Cells[1].Value = p.GetValue(targets[i].OS[k], null);
                                   }
                                }
                            }

                            //registry DGV
                            registrydgv.DataSource =targets[i].r1;
                            registrydgv.RowHeadersVisible = false;
                            registrydgv.AutoResizeColumns();
                            for (int j = 0; j < application_dgv.Columns.Count; j++)
                            {

                                try
                                {
                                    if (string.IsNullOrEmpty(application_dgv.Rows[1].Cells[j].Value.ToString()) == true || application_dgv.Rows[1].Cells[j].Value == "")
                                    {
                                        this.application_dgv.Columns[j].Visible = false;
                                    }
                                }
                                catch
                                {

                                }
                            }
                            this.application_dgv.Columns["assign_type"].Visible = false;
                            application_dgv.RowHeadersVisible = false;
                            application_dgv.AutoResizeColumns();
                            dataGridView1.AutoResizeColumns();
                            break;
                        }

                    }
                }
            }
        }
        private void tree_color(string remoteHostName, Color c1)
        {
            //_rw.EnterWriteLock();
            host = remoteHostName;

            for (int i = 0; i < treeView1.Nodes[0].Nodes.Count; i++)
            {
                string[] classC = treeView1.Nodes[0].Nodes[i].Text.Split('.');
                if (host.Contains(classC[0] + "." + classC[1] + "." + classC[2] + "."))
                {
                    for (int j = 0; j < treeView1.Nodes[0].Nodes[i].Nodes.Count; j++)
                    {
                        if (treeView1.Nodes[0].Nodes[i].Nodes[j].Text == host)
                        {
                            treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = c1;
                            break;
                        }
                    }
                    break;
                }
            }
        }

        private void tree_color(string remoteHostName, bool add, string message)
        {
            //_rw.EnterWriteLock();
            host = remoteHostName;

            for (int i = 0; i < treeView1.Nodes[0].Nodes.Count; i++)
            {
                string[] classC = treeView1.Nodes[0].Nodes[i].Text.Split('.');
                if (host.Contains(classC[0] + "." + classC[1] + "." + classC[2] + "."))
                {
                    for (int j = 0; j < treeView1.Nodes[0].Nodes[i].Nodes.Count; j++)
                    {
                        if (treeView1.Nodes[0].Nodes[i].Nodes[j].Text == host)
                        {
                            //treeView1.Nodes[0].Nodes[i].Nodes[j].ForeColor = c1;
                            if (add)
                            {
                                treeView1.Nodes[0].Nodes[i].Nodes[j].Nodes.Add(message);
                                if (message.ToLower().Contains("error"))
                                    treeView1.Nodes[0].Nodes[i].Nodes[j].Nodes[treeView1.Nodes[0].Nodes[i].Nodes[j].Nodes.Count - 1].ForeColor = Color.Red;
                            }
                            break;
                        }
                    }
                    break;
                }
            }
        }
        #endregion

        #region newIOcontrol
        private class AllAboutIO
        {
            public AllAboutIO(StreamReader reader)
            {
                this.reader = reader;
            }

            public string result;
            public StreamReader reader;
        }

        public string stdout;
        public string stderr;

        public void AsyncStreamReader(object data)
        {
            AllAboutIO myData = (AllAboutIO)data;
            myData.result = myData.reader.ReadToEnd();
        }

        public int Run(string Program, string Arguments, string host)
        {
            Process myProc = new Process();

            myProc.StartInfo.UseShellExecute = false;
            myProc.StartInfo.FileName = Program;
            myProc.StartInfo.Arguments = Arguments;
            myProc.StartInfo.CreateNoWindow = true;
            myProc.StartInfo.RedirectStandardError = true;
            myProc.StartInfo.RedirectStandardOutput = true;

            try
            {
                if (myProc.Start())
                {
                    AllAboutIO stdoutReader = new AllAboutIO(myProc.StandardOutput);
                    AllAboutIO stderrReader = new AllAboutIO(myProc.StandardError);

                    Thread readStdOutThread = new Thread(this.AsyncStreamReader);
                    Thread readStdErrThread = new Thread(this.AsyncStreamReader);

                    readStdOutThread.Start(stdoutReader);
                    readStdErrThread.Start(stderrReader);

                    myProc.WaitForExit();

                    readStdErrThread.Join();
                    readStdOutThread.Join();

                    stdout = stdoutReader.result;
                    stderr = stderrReader.result;

                    return myProc.ExitCode;
                }
                else
                {
                    stderr = "Process did not start. Verify that the program exists at the specified location.";
                    return 1;
                }
            }
            catch (System.Exception excp)
            {
                stderr = "Failed to launch the process: " + excp.Message;
                return 1;
            }
        }
        #endregion
        #region Proc Start(s)
        private int run_packages_py(string args, string host, int os)
        {
            string executable = string.Empty;
            if (os == 0)
                executable = "packages_bak.exe";
            else
                executable = "packages.exe";
            // This is the code for the base process
            Process proc = new Process();
            // Start a new instance of this program but specify the 'spawned' version.
            ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(executable, args);
            myProcessStartInfo.UseShellExecute = false;
            myProcessStartInfo.CreateNoWindow = true;
            myProcessStartInfo.RedirectStandardOutput = true;
            myProcessStartInfo.RedirectStandardError = true;
            proc.StartInfo = myProcessStartInfo;
            proc.Exited += new EventHandler(ProcExitHandler);
            proc.EnableRaisingEvents = true;
            proc.Start();
           // StreamReader myStreamReader = myProcess.StandardOutput;
            // Read the standard output of the spawned process.
            //string myString = myStreamReader.ReadLine();
            //string error = myProcess.BeginErrorReadLine();
            //Console.WriteLine(myString);
            sb = new StringBuilder();
            DataReceivedEventHandler outputDataHandler = new DataReceivedEventHandler(SortOutputHandler);
            //StreamWriter input = proc.StandardInput;
            proc.OutputDataReceived += outputDataHandler;
            proc.ErrorDataReceived += outputDataHandler;


            // start reading the stdout and stderr
            proc.BeginErrorReadLine();
            proc.BeginOutputReadLine();
            
            proc.WaitForExit();
            int exit = proc.ExitCode;
            proc.Close();
            //_rw.EnterWriteLock();
            if (installpkg_scan && os < 1)
                sbtoList(host,os);
            if (misc_scan && os > 0)
                sbtoList(host, os);
            //_rw.ExitWriteLock();
            return exit;
        }

        private int run_reg_csharp(string machine, string subkey)
        {
            int exit = 0;
            host = machine;
            int ndx = targets.FindIndex(FindTarget);
            targets[ndx].r1 = regg.do_regread(machine, subkey);
            return exit;
        }

        #region deprecated proc starts
        private int run_wmic(string args, string host)
        {

            // This is the code for the base process
            Process proc = new Process();
            // Start a new instance of this program but specify the 'spawned' version.
            ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("wmic", args);
            myProcessStartInfo.UseShellExecute = false;
            myProcessStartInfo.CreateNoWindow = true;
            myProcessStartInfo.RedirectStandardOutput = true;
            myProcessStartInfo.RedirectStandardError = true;
            proc.StartInfo = myProcessStartInfo;
            proc.Start();
            // StreamReader myStreamReader = myProcess.StandardOutput;
            // Read the standard output of the spawned process.
            //string myString = myStreamReader.ReadLine();
            //string error = myProcess.BeginErrorReadLine();
            //Console.WriteLine(myString);
            sb = new StringBuilder();
            DataReceivedEventHandler outputDataHandler = new DataReceivedEventHandler(SortOutputHandler);
            //StreamWriter input = proc.StandardInput;
            proc.OutputDataReceived += outputDataHandler;
            proc.ErrorDataReceived += outputDataHandler;
            proc.Exited += new EventHandler(ProcExitHandler);
            proc.EnableRaisingEvents = true;

            // start reading the stdout and stderr
            proc.BeginErrorReadLine();
            proc.BeginOutputReadLine();

            proc.WaitForExit();
            int exit = proc.ExitCode;
            proc.Close();
            //_rw.EnterWriteLock();

            sbtoList(host);
            //_rw.ExitWriteLock();
            return exit;


        }
        private int run_regq(string[] args, string host)
        {
                                //query            //127.0.0.1    //HKLM...  // /s
            string arg_resort = args[0] + " \\\\" + host + "\\" + args[1] +" "+args[2]; 
            // This is the code for the base process
            Process proc = new Process();
            // Start a new instance of this program but specify the 'spawned' version.
            ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("reg", arg_resort);
            myProcessStartInfo.UseShellExecute = false;
            myProcessStartInfo.CreateNoWindow = true;
            myProcessStartInfo.RedirectStandardOutput = true;
            myProcessStartInfo.RedirectStandardError = true;
            proc.StartInfo = myProcessStartInfo;
            proc.Start();
            // StreamReader myStreamReader = myProcess.StandardOutput;
            // Read the standard output of the spawned process.
            //string myString = myStreamReader.ReadLine();
            //string error = myProcess.BeginErrorReadLine();
            //Console.WriteLine(myString);
            sb = new StringBuilder();
            DataReceivedEventHandler outputDataHandler = new DataReceivedEventHandler(SortOutputHandler);
            //StreamWriter input = proc.StandardInput;
            proc.OutputDataReceived += outputDataHandler;
            proc.ErrorDataReceived += outputDataHandler;
            proc.Exited += new EventHandler(ProcExitHandler);
            proc.EnableRaisingEvents = true;

            // start reading the stdout and stderr
            proc.BeginErrorReadLine();
            proc.BeginOutputReadLine();

            proc.WaitForExit();
            int exit = proc.ExitCode;
            proc.Close();
            //_rw.EnterWriteLock();

            sbtoList(host, true);
            //_rw.ExitWriteLock();
            return exit;
        }
        #endregion
        #endregion

        #region StringBuilders to Lists
        private void sbtoList(string ipaddr, int packages_bool)
        {
            ////_rw.EnterWriteLock();
            host = ipaddr;
            Targets t1 = new Targets();
            int ndx = targets.FindIndex(FindTarget);
            ////_rw.ExitWriteLock();
            //char[] separate = new char[1] { '$', };
            //string[] pods = sb.ToString().Split(separate);
            if (sb.ToString().Contains("ERROR") && !(sb.ToString().Contains("User credentials cannot be used for local connections")))
            {
                targets[ndx].SetKillSwitch(true);
                readData = sb.ToString();
            }

            if (sb.ToString().Contains("Bad authentication type"))
            {
                //do nothing, because we will run another attempt
                //maybe make the 
            }
            else
            {
                if (!(String.IsNullOrEmpty(sb.ToString())) || !(sb.ToString() == "None"))
                {
                    t1.wup = targets[ndx].wup;
                    //t1.appitemz = targets[ndx].appitemz;
                    t1.domain = targets[ndx].domain;
                    t1.full_name = targets[ndx].full_name;
                    t1.ipaddr = targets[ndx].ipaddr;
                    t1.misc = targets[ndx].misc;
                    t1.name = targets[ndx].name;
                    if (packages_bool == 0)
                    {
                        t1.OS = targets[ndx].OS;

                        Type t = t1.appitemz.GetType();

                        string[] s = sb.ToString().Split('\n');
                        foreach (string final in s)
                        {
                            ApplicationItem app = new ApplicationItem();
                            try
                            {
                                if (final.Length > 0)
                                {
                                    string really = final.Trim('\r');

                                    string[] value = really.Split(' ');
                                    app.name = value[0];
                                    app.caption = value[0];
                                    if (!(String.IsNullOrEmpty(value[1])))
                                    {
                                        app.version = value[1];
                                    }
                                }
                                t1.appitemz.Add(app);
                            }
                            catch
                            { }
                        }

                        //}
                        // }
                    }
                    else
                    {
                        t1.appitemz = targets[ndx].appitemz;

                        Type t = t1.OS.GetType();

                        string[] s = sb.ToString().Split('\n');
                        foreach (string final in s)
                        {
                            OSystem os = new OSystem();
                            try
                            {
                                if (final.Length > 0)
                                {
                                    string really = final.Trim('\r');

                                    string[] value = really.Split(' ');
                                    os.Name = value[0];
                                    // = value[0];
                                    if (!(String.IsNullOrEmpty(value[1])))
                                    {
                                        os.Version = value[1];
                                    }
                                }
                                t1.OS.Add(os);
                            }
                            catch
                            { }
                        }
                    }
                    targets.Insert(ndx, t1);
                    targets.RemoveAt(ndx + 1);
                }
                else
                {
                    if (sb.ToString() == "None")
                    {
                        //pop up with a credentials box, unless there is truly none...

                    }

                }
            }
        }

        private void sbtoList(string ipaddr)
        {
            ////_rw.EnterWriteLock();
            host = ipaddr;
            Targets t1 = new Targets();
            int ndx = targets.FindIndex(FindTarget);
            ////_rw.ExitWriteLock();
            char[] separate = new char[1] {'$',};
            string[] pods = sb.ToString().Split(separate);
            if (sb.ToString().Contains("ERROR")  && !(sb.ToString().Contains("User credentials cannot be used for local connections")))
            {
                targets[ndx].SetKillSwitch(true);
                readData = sb.ToString(); 
            }
            if (sb.ToString().Contains("Caption"))
            {

               
                t1.appitemz = targets[ndx].appitemz;
                t1.domain = targets[ndx].domain;
                t1.full_name = targets[ndx].full_name;
                t1.ipaddr = targets[ndx].ipaddr;
                t1.misc = targets[ndx].misc;
                t1.name = targets[ndx].name;
                t1.os = targets[ndx].os;
                // make our list now
                
                //t1.wup

                Type t = t1.wup.GetType();
             
                    //0. Split on ';'
                    //1. Split on '='
                    //  a. str[0] is property
                    //  b. str[1] is value
                    foreach ( string str in pods)
                    {
                        if (str.Length > 0)
                        {
                            WindowsUpdate w = new WindowsUpdate();
                            string[] s = str.Split('\n');
                            foreach (string final in s)
                            {
                                string really = final.Trim('\r');
                                
                                string[] value = really.Split('=');
                                switch (value[0])
                                {
                                    case "Caption":
                                        w.Caption = value[1];
                                        break;
                                    case "CSName":
                                        w.CSName = value[1];
                                        break;
                                    case "Description":
                                        w.Desc = value[1];
                                        break;
                                    case "FixComments":
                                        w.FixComment = value[1];
                                        break;
                                    case "HotFixID":
                                        w.HotFixID = value[1];
                                        break;
                                    case "InstallDate":
                                        w.InstallDate = value[1];
                                        break;
                                    case "InstalledBy":
                                        w.InstallBy = value[1];
                                        break;
                                    case "InstalledOn":
                                        w.InstalledOn = value[1];
                                        break;
                                    case "Name":
                                        w.Name = value[1];
                                        break;
                                    case "ServicePackInEffect":
                                        w.ServicePack = value[1];
                                        break;
                                    case "Status":
                                        w.Status = value[1];
                                        break;
                                    default:
                                        break;
                                }
                            }
                            t1.wup.Add(w);
                        }
                    }
                 
                targets.Insert(ndx, t1);
                targets.RemoveAt(ndx + 1);
            }
        }

        private void sbtoList(string ipaddr, bool runreg)
        {
            ////_rw.EnterWriteLock();
            host = ipaddr;
            string[] test = sb.ToString().Split(new string[] {"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" }, StringSplitOptions.RemoveEmptyEntries);
            int howmany = test.Length;
            //Targets t1 = new Targets();
            //int ndx = targets.FindIndex(FindTarget);
            //////_rw.ExitWriteLock();
            //char[] separate = new char[1] { '$', };
            //string[] pods = sb.ToString().Split(separate);
            //if (sb.ToString().Contains("ERROR") && !(sb.ToString().Contains("User credentials cannot be used for local connections")))
            //{
            //    targets[ndx].SetKillSwitch(true);
            //    readData = sb.ToString();
            //}
            //if (sb.ToString().Contains("Caption"))
            //{


            //    t1.appitemz = targets[ndx].appitemz;
            //    t1.domain = targets[ndx].domain;
            //    t1.full_name = targets[ndx].full_name;
            //    t1.ipaddr = targets[ndx].ipaddr;
            //    t1.misc = targets[ndx].misc;
            //    t1.name = targets[ndx].name;
            //    t1.os = targets[ndx].os;
            //    // make our list now

                //t1.wup

            //    Type t = t1.wup.GetType();

            //    //0. Split on ';'
            //    //1. Split on '='
            //    //  a. str[0] is property
            //    //  b. str[1] is value
            //    foreach (string str in pods)
            //    {
            //        if (str.Length > 0)
            //        {
            //            WindowsUpdate w = new WindowsUpdate();
            //            string[] s = str.Split('\n');
            //            foreach (string final in s)
            //            {
            //                string really = final.Trim('\r');

            //                string[] value = really.Split('=');
            //                switch (value[0])
            //                {
            //                    case "Caption":
            //                        w.Caption = value[1];
            //                        break;
            //                    case "CSName":
            //                        w.CSName = value[1];
            //                        break;
            //                    case "Description":
            //                        w.Desc = value[1];
            //                        break;
            //                    case "FixComments":
            //                        w.FixComment = value[1];
            //                        break;
            //                    case "HotFixID":
            //                        w.HotFixID = value[1];
            //                        break;
            //                    case "InstallDate":
            //                        w.InstallDate = value[1];
            //                        break;
            //                    case "InstalledBy":
            //                        w.InstallBy = value[1];
            //                        break;
            //                    case "InstalledOn":
            //                        w.InstalledOn = value[1];
            //                        break;
            //                    case "Name":
            //                        w.Name = value[1];
            //                        break;
            //                    case "ServicePackInEffect":
            //                        w.ServicePack = value[1];
            //                        break;
            //                    case "Status":
            //                        w.Status = value[1];
            //                        break;
            //                    default:
            //                        break;
            //                }
            //            }
            //            t1.wup.Add(w);
            //        }
            //    }

            //    targets.Insert(ndx, t1);
            //    targets.RemoveAt(ndx + 1);
            //}
        }
        #endregion

        #region Proc IO handlers
        private static void ProcExitHandler(object sender, EventArgs e)
        {
            //myProcess.Dispose();
            //myProcess = null;
        }
        private void SortOutputHandler(object sendingProcess,
           DataReceivedEventArgs outLine)
        {
            if (!String.IsNullOrEmpty(outLine.Data))
            {
                if (outLine.Data.ToString().Contains("Bad authentication type")) // || outLine.Data.ToString().Contains("Code") || outLine.Data.ToString().Contains("local connections"))
                {
                    //sb.AppendLine(outLine.Data.ToString());
                }
                //{
                //    //readData = outLine.Data.ToString();
                //    //LogTextEvent(richTextBox1, Color.Black, readData);
                //}
                //if (outLine.Data.ToString().Contains("CSName"))
                //{
                //    readData = "Found: " + outLine.Data.ToString();
                //    LogTextEvent(richTextBox1, Color.Black, readData);
                //}
                if (outLine.Data.ToString().Contains("Caption"))
                {
                    sb.Append("$");
                }
                sb.Append(outLine.Data.ToString()).AppendLine();
                //only want errors or things of interest back to the user - readData
                //readData = outLine.Data.ToString();
            }
        }
        #endregion
        #region Form Message Feedback
        public void msg()
        {
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new MethodInvoker(msg));
                    //this.Close();
                }
                else
                {
                    //if (readData.ToLower().Contains("error"))
                    //{
                    //    richTextBox1.SelectionColor = Color.Red;
                    //}
                    //else
                    //    richTextBox1.SelectionColor = Color.Black;
                    this.richTextBox1.Text = this.richTextBox1.Text + Environment.NewLine + " >> " + readData;
                    richTextBox1.ScrollToCaret();
                   // richTextBox1.SelectedText = Environment.NewLine + " >> " + readData;
                }
            }
            catch (Exception e)
            {

                //MessageBox.Show("Thread error... \n  This is usually caused by the Application exiting while a thread still contains data to pass\n");
            }
        }

        public void LogTextEvent(RichTextBox TextEventLog, Color TextColor, string EventText)
        {
            if (TextEventLog.InvokeRequired)
            {
                TextEventLog.BeginInvoke(new Action(delegate
                {
                    LogTextEvent(TextEventLog, TextColor, EventText);
                }));
                return;
            }

            //string nDateTime = DateTime.Now.ToString("hh:mm:ss tt") + " - ";
            TextEventLog.SelectionColor = TextColor;

            TextEventLog.SelectedText = Environment.NewLine + " >>  " + EventText;
            TextEventLog.ScrollToCaret();
        }
        #endregion

        #region Misc Form stuff (Load, click events, alignment, resize)
        private void Form1_Load(object sender, EventArgs e)
        {
            this.naviBar2.ActiveBand = naviBand2;
            this.ShowIcon = false;
            //naviGroup2.Expand();
            ToolTip tool1 = new ToolTip();
            //tool1.SetToolTip(this.newScanbtn0, "Start Scan");
        }

        private void Form1_ResizeEnd(object sender, EventArgs e)
        {
            //Allign buttons, etc.. etc...
            foreach (object btn in this.splitContainer1.Panel1.Controls)
            {
                if (btn.GetType() == typeof(Button))
                {
                    int factor = System.Convert.ToInt32((btn as Button).Name.Substring((btn as Button).Name.Length - 1));
                    allignment((btn as Button), factor);
                }
            }
        }

        private void allignment(Button btn, int factor)
        {
            int x = this.splitContainer1.Panel1.Width;
            int wide = this.splitContainer1.Panel1.Width - 20;
            int y = this.Height;

            btn.Size = new System.Drawing.Size(wide, y / 6);
            //whatever 600/75 is our divider for size
            //whatever 600/25 is our divider for y
            btn.Location = new Point((x - wide) / 2, ((y / 6) / 3) + factor * ((y / 6) + (y / 6 / 3)));
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {

            try
            {
                if (ScanThread.Length > 0)
                {
                    for (int t = ScanThread.Length; t >= 0; t--)
                    {
                        try
                        {
                            ScanThread[t].Abort();
                        }
                        catch (Exception e1)
                        {
                            System.Diagnostics.Debug.WriteLine("Problem shutting down thread.\n " + e1);
                        }
                    }
                }
            }
            catch
            {

            }
            Application.Exit();
        }



        private void toCSVToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //save file dialog
            SaveFileDialog save = new SaveFileDialog();
            save.Filter = "CSV File|*.csv";
            save.Title = "Export to .csv";
            save.ShowDialog();

            if (save.FileName != "")
            {
                if (targets[0].appitemz.Count > 0 && targets[0].wup.Count > 0)
                    write_csv(save.FileName);
                MessageBox.Show("Scan data exported to .csv successfully!");
            }
            else
            {
                MessageBox.Show("Invalid filename\nPlease try again.");
            }
        }

        

        private void toXMLToolStripMenuItem_Click(object sender, EventArgs e)
        {

            SaveFileDialog save = new SaveFileDialog();
            save.Filter = "XML File|*.xml";
            save.Title = "Export to .xml";
            save.ShowDialog();

            if (save.FileName != "")
            {
                if (targets[0].appitemz.Count > 0 && targets[0].wup.Count > 0)
                   // write_csv(save.FileName);
                write_XML(save.FileName);
                MessageBox.Show("Scan data exported to .xml successfully!");
            }
            else
            {
                MessageBox.Show("Invalid filename\nPlease try again.");
            }
            
        }

        private void newScanToolStripMenuItem_Click(object sender, EventArgs e)
        {
            newScanbtn_Click(sender, e);
        }

        private void treeView1_Click(object sender, EventArgs e)
        {
            try
            {
                treeView1_AfterSelect((sender as TreeView), (e as TreeViewEventArgs));
            }
            catch
            {
            }
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox1 about = new AboutBox1();
            about.ShowDialog();
        }

        private void ExportBtn1_Click(object sender, EventArgs e)
        {
            //save file dialog
            SaveFileDialog save = new SaveFileDialog();
            save.Filter = "CSV File|*.csv|XML File|*.xml";
            save.Title = "Export to .csv or .xml";
            if (!bscanning)
            {
                save.ShowDialog();

                if (save.FileName != "" && targets.Count > 0)
                {
                    if (save.FileName.Split('.')[save.FileName.Split('.').Length - 1].ToLower().Contains("csv"))
                    {
                        //if (targets[0].appitemz.Count > 0 && targets[0].wup.Count > 0)
                        write_csv(save.FileName);
                        MessageBox.Show("Scan data exported to .csv successfully!");
                        exported = true;
                    }
                    if (save.FileName.Split('.')[save.FileName.Split('.').Length - 1].ToLower().Contains("xml"))
                    {
                        //if (targets[0].appitemz.Count > 0 && targets[0].wup.Count > 0)
                        write_XML(save.FileName);
                        MessageBox.Show("Scan data exported to .xml successfully!");
                        exported = true;
                    }
                }
                else
                {
                    if (targets.Count > 0)
                        MessageBox.Show("Invalid filename\nPlease try again.");
                    else
                        MessageBox.Show("No records to export!\n Try running a new scan.");
                }
            }
            else
                MessageBox.Show("Scan is still running!\nPlease abort current scan\n and try again!");

        }

        #endregion

        private string resolver(string IP)
        {
            string name = String.Empty;
            //attempt to resolve Machine name for credentials if we have credential mismatch error or if resolve is turned on.
            //Try dns first ?
            //or smb?
            try
            {
                IPHostEntry something = Dns.GetHostEntry(IP);
                name = something.HostName.ToString();
            }
            catch
            {

            }
            return name;
        }

        private void registrydgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //Select column under header
            
            // Check which column is selected, otherwise set NewColumn to null.
            DataGridViewColumn newColumn = (sender as DataGridView).Columns[e.ColumnIndex];
                //registrydgv.Columns.GetColumnCount(
                //DataGridViewElementStates.Selected) == 1 ?
                //registrydgv.SelectedColumns[0] : null;

            //DataGridViewColumn oldColumn = registrydgv.SortedColumn;
            //ListSortDirection direction;

            //// If oldColumn is null, then the DataGridView is not currently sorted.
            //if (oldColumn != null)
            //{
            //    // Sort the same column again, reversing the SortOrder.
            //    if (oldColumn == newColumn &&
            //        dataGridView1.SortOrder == SortOrder.Ascending)
            //    {
            //        direction = ListSortDirection.Descending;
            //    }
            //    else
            //    {
            //        // Sort a new column and remove the old SortGlyph.
            //        direction = ListSortDirection.Ascending;
            //        oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
            //    }
            //}
            //else
            //{
            //    direction = ListSortDirection.Ascending;
            //}

            //// If no column has been selected, display an error dialog  box.
            //if (newColumn == null)
            //{
            //    MessageBox.Show("Select a single column and try again.",
            //        "Error: Invalid Selection", MessageBoxButtons.OK,
            //        MessageBoxIcon.Error);
            //}
            //else
            //{
            //    registrydgv.Sort(newColumn, direction);
            //    newColumn.HeaderCell.SortGlyphDirection =
            //        direction == ListSortDirection.Ascending ?
            //        SortOrder.Ascending : SortOrder.Descending;
            //}
        }

        private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
        {

        }

        private void naviGroup1_Click(object sender, EventArgs e)
        {

        }

        private void button4_Click(object sender, EventArgs e)
        {
            newScanbtn_Click(sender, e);
        }


    }
}
